﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using Common.Logging;
using Framework.Core.Queue;
using System.ComponentModel;
using System.Threading;

namespace Framework.Message.SMS.CommonLibrary
{
    public abstract class BaseClient<SequenceT>
    {
        #region 变量与属性
        private BaseGatewaySetting _GatewaySetting;

        public BaseGatewaySetting GatewaySetting
        {
            get { return _GatewaySetting; }
            set { _GatewaySetting = value; }
        }

        private BaseClientSetting _Setting;

        public BaseClientSetting Setting
        {
            get { return _Setting; }
            set { _Setting = value; }
        }

        /// <summary>
        /// 发命令套字节
        /// </summary>
        private Socket _SendCommandSocket = null;
        //private Socket _DeliveCommandSocket = null;
        /// <summary>
        /// 本服务是否在运行
        /// </summary>
        protected bool _IsStarted = false;
        /// <summary>
        /// 是否已经登录    
        /// </summary>
        protected bool _IsLogin = false;
        /// <summary>
        /// 日志组件
        /// </summary>
        protected ILog Logger = null;
        /// <summary>
        /// 最后正确发送消息时间
        /// </summary>
        protected DateTime _LastActiveTime;

        /// <summary>
        /// 得到下一个排队序号
        /// </summary>
        /// <returns></returns>
        protected abstract SequenceT NextSequence
        {
            get;
        }

        /// <summary>
        /// 命令头长度
        /// </summary>
        protected abstract uint CommandHeaderLength
        {
            get;
        }

        protected DateTime _LastPingTime = DateTime.Now;
        /// <summary>
        /// 是否到了ping一次的时间
        /// </summary>
        protected virtual bool IsPingTime
        {
            get
            {
                TimeSpan ts = (DateTime.Now - this._LastPingTime);
                return ts.TotalSeconds >= Setting.PingTick;
            }
        }

        protected virtual bool IsSocketActive
        {
            get
            {
                TimeSpan ts = (DateTime.Now - this._LastActiveTime);
                return ts.TotalSeconds < Setting.TimeoutTick;
            }
        }

        #region 线程
        /// <summary>
        /// 链接监测线程
        /// </summary>
        private BackgroundWorker _MonitoringThread = null;
        /// <summary>
        /// 发送命令线程
        /// </summary>
        private BackgroundWorker _SendCommandThread = null;
        /// <summary>
        /// 接收命令线程
        /// </summary>
        private BackgroundWorker _ReceiveCommandThread = null;

        #endregion

        #region 队列
        /// <summary>
        /// 待发送队列
        /// </summary>
        //private IStatusQueue<string, BaseCommand, CommandInQueueStatus> _CommandQueue = new BaseStatusQueue<string, BaseCommand, CommandInQueueStatus>();
        ///// <summary>
        ///// 已发送队列
        ///// </summary>
        //private IStatusQueue<string, BaseCommand, CommandInQueueStatus> _SentCommandQueue = new BaseStatusQueue<string, BaseCommand, CommandInQueueStatus>();
        #endregion
        #endregion

        public BaseClient(BaseGatewaySetting gatewaySetting)
        {
            Logger = LogManager.GetLogger(this.GetType().FullName);
            _GatewaySetting = gatewaySetting;
        }

        protected virtual void StopClient()
        {
            lock (this)
            {
                this._IsStarted = false;
            }
        }


        #region 线程处理函数
        protected virtual void ThreadsStart()
        {
            Logger.Debug("启动线程。");
            _MonitoringThread = new BackgroundWorker();
            _MonitoringThread.DoWork += new DoWorkEventHandler(MonitoringThread_DoWork);
            _MonitoringThread.RunWorkerAsync();

            _SendCommandThread = new BackgroundWorker();
            _SendCommandThread.DoWork += new DoWorkEventHandler(SendCommandThread_DoWork);

            _ReceiveCommandThread = new BackgroundWorker();
            _ReceiveCommandThread.DoWork += new DoWorkEventHandler(ReceiveCommandThread_DoWork);
            _ReceiveCommandThread.RunWorkerAsync();
        }

        private void ReceiveCommandThread_DoWork(object sender, DoWorkEventArgs e)
        {
            List<byte> receiveBuf = new List<byte>();
            while (this._IsStarted)
            {
                try
                {
                    byte[] thisBuf = new byte[10240];
                    int thisMsgLength = this._SendCommandSocket.Receive(thisBuf);
                    Logger.Debug(string.Format("本次收到{0}个字节。", thisMsgLength));
                    if (thisMsgLength > 0)
                    {
                        for (int i = 0; i < thisMsgLength; i++)
                        {
                            receiveBuf.Add(thisBuf[i]);
                        }
                        Logger.Debug(string.Format("{0}个字节数据被加到接收缓存里。缓存里还存在{1}个字节。", thisMsgLength, receiveBuf.Count));
                        //先取命令头信息获取命令基本信息。
                        if (receiveBuf.Count >= this.CommandHeaderLength)
                        {
                            byte[] headerBytes = new byte[this.CommandHeaderLength];
                            for (int i = 0; i < this.CommandHeaderLength; i++)
                            {
                                headerBytes[i] = receiveBuf[i];
                            }
                            //CommandHeader header = new CommandHeader(headerBytes);
                            //Logger.Debug(string.Format("收到的命令类型为{0}，长度为{1}，序列为。", header.CommandID, header.MessageLength, header.SequenceNumber.ToString()));
                            //if (receiveBuf.Count >= header.MessageLength)
                            //{
                            //    byte[] commandBytes = new byte[header.MessageLength];
                            //    for (int i = 0; i < header.MessageLength; i++)
                            //    {
                            //        commandBytes[i] = receiveBuf[0];
                            //        receiveBuf.RemoveAt(0);
                            //    }

                            //    Command command = CommandFactory.GetCommandFormByte(commandBytes);

                            //    if (command != null)
                            //    {

                            //    }
                            //    this._CommandQueue.Remove(header.SequenceNumber.ToString());
                            //    Logger.Debug(string.Format("命令【{0}】从已发送队列中移出。", header.SequenceNumber.ToString()));
                            //}
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.Debug("接收数据线程发生异常。", ex);
                    this._IsStarted = false;
                }
                Thread.Sleep(50);
            }
            Logger.Debug("接收数据线程结束。");
        }

        private void SendCommandThread_DoWork(object sender, DoWorkEventArgs e)
        {
            while (this._IsStarted)
            {
                if (this._IsLogin)
                {
                    //List<CommandInQueueStatus> status = new List<CommandInQueueStatus>();
                    //status.Add(CommandInQueueStatus.New);
                    //IList<IStatusQueuer<string, Command, CommandInQueueStatus>> list = this._CommandQueue.GetTopNQueuers(16, status);
                    //foreach (IStatusQueuer<string, Command, CommandInQueueStatus> item in list)
                    //{
                    //    #region 发送信息
                    //    switch (item.Value.Header.CommandID)
                    //    {
                    //        case SGIPCommandType.Unbind:
                    //            break;
                    //        case SGIPCommandType.Unbind_Resp:
                    //            break;
                    //        case SGIPCommandType.Submit:
                    //            lock (this)
                    //            {
                    //                item.Status = CommandInQueueStatus.Sending;
                    //            }
                    //            this.SendCommand(item.Value);
                    //            break;
                    //        case SGIPCommandType.Deliver_Resp:
                    //            lock (this)
                    //            {
                    //                item.Status = CommandInQueueStatus.Sent;
                    //            }
                    //            this.SendCommand(item.Value);
                    //            break;
                    //        case SGIPCommandType.Report:
                    //            lock (this)
                    //            {
                    //                item.Status = CommandInQueueStatus.Sending;
                    //            }
                    //            this.SendCommand(item.Value);
                    //            break;
                    //        default:
                    //            break;
                    //    }
                    //    #endregion
                    //}
                }
            }
        }

        private void MonitoringThread_DoWork(object sender, DoWorkEventArgs e)
        {
            while (this._IsStarted)
            {
                //if (IsSocketActive)
                //{
                //    if (this.IsPingTime)
                //    {
                //        this.Ping();
                //    }
                //}
                //else
                //{
                //    this._IsStarted = false;
                //}
                Thread.Sleep(50);
            }
            Logger.Debug("连接检测线程结束。");
        }
        #endregion

    }
}
